#coding:utf8
from config import *

to_lock = threading.Lock()
xing_q = deque([], 3)

def deal_xing_q():
    global xing_q
    xing_q.append(time.time())
    if len(xing_q) == 3 and xing_q[-1] - xing_q[0] < 0.8:        
        cfg.show_mouse_tip = False        
        clear(True)
        print('xing clear')
        
def x2_d_to_dst():
    dx = (cfg.snap[-1][1] -  cfg.snap[0][1]) * cfg.x2_mode_d / 100 + cfg.snap[0][1]
    dy = (cfg.snap[-1][2] -  cfg.snap[0][2]) * cfg.x2_mode_d / 100 + cfg.snap[0][2]
    cfg.x2_mode_dst = (round(dx), round(dy))


def getdu(mouse_pos=None):
    x, y = get_cur_pos()
    if mouse_pos:
        x, y = mouse_pos
    sx, sy = cfg.fix_pos
    dx = x - sx
    dy = y - sy
    du0 = math.atan2(dy, dx)
    s = sca_l[cfg.sca%len(sca_l)]
    d =  du0 -cfg.sca_cur
    if d >  math.pi:
        d -= 2 * math.pi
    if d < - math.pi:
        d += 2 * math.pi
    du = cfg.sca_du + d * s
    if is_sca():
        x, y = cfg.sca_cur_pos
        dx = x - sx
        dy = y - sy
    ll = math.sqrt(dx*dx+dy*dy)
    return du, ll

def getp(mouse_pos=None, doRound=True):
    du, ll = getdu(mouse_pos)
    sx, sy = cfg.fix_pos
    if doRound:
        return round(ll * math.cos(du) + sx), round(ll * math.sin(du) + sy)
    else:
        return ll * math.cos(du) + sx, ll * math.sin(du) + sy

def cal_mouse_d(sp):
    pos = get_cur_pos()
    dx = pos[0] - sp[0]
    dy = pos[1] - sp[1]
    return math.sqrt(dx*dx+dy*dy)


def cut_to(d):    
    if d > max_l:
        d =  max_l
    if d < 0:
        d = 0
    return d
    
def dotdot():    
    if cfg.isShow:
        cfg.isShow = False                
        cfg.show_one_on = False
        return
    
    if cfg.w2showing:        
        cfg.show_one_on = False
        return
    
    cfg.show_one_on = True
    cfg.show_one_onetime = True

def lock_add():    
    cfg.lock_step = min(cfg.lock_step + 1, len(lock_l) -1) 
    
def lock_min():    
    if cfg.lock_step == 0:        
        dotdot()
        return
    cfg.lock_step = max(0, cfg.lock_step - 1)
    
def lock_get():
    return lock_l[cfg.lock_step%len(lock_l)]
   


def update_du(add):    
    du, ll = getdu()
    cfg.sca_du = du
    if add:
        cfg.sca += 1
    x, y = get_cur_pos()
    sx, sy = cfg.fix_pos
    dx = x - sx
    dy = y - sy
    cfg.sca_cur = math.atan2(dy, dx)
    cfg.sca_cur_pos = (x, y)

def deal_manu_scroll(aa=0):
    if aa == 0:
        if '0.' in cfg.sum:
            d = -int(cfg.sum.replace('0.', '') )
        else:
            d = int(cfg.sum)
    else:
        d = aa
    if d == -1:
        d = -2
    dd = cal_dis(get_cur_pos(), cfg.fix_pos)
    to_lock.acquire()
    if dd > min_d:
        cfg.to = cut_to(cfg.to+d*dd)
    else:
        cfg.to = cut_to(cfg.to+d*min_d)
    
    set_to_change_time()
    to_lock.release()
    cfg.sum = '0'    

def deal_fix_scroll():
    if '0.' in cfg.sum:
        d = -int(cfg.sum.replace('0.', '') )
    else:
        d = int(cfg.sum)    
    cfg.fix_scroll = d
    cfg.sum = '0'

def xing():    
    if cfg.sum != '0':
        if '0.0' in cfg.sum:
            cfg.force_scroll = not cfg.force_scroll
            return
        deal_fix_scroll()
        return
    
    oriIsshow = cfg.isShow
    cfg.isShow = False
    ori = cfg.force_show
    clear(True)
    if cfg.w2showing or oriIsshow:
        cfg.show_one_on = False
        return
    
    if not cfg.show_one_on:
        cfg.show_one_on = True
        cfg.force_show = True
        return
    if ori:
        cfg.show_one_on = False
        cfg.force_show = False
        return
    cfg.force_show = True

def deal_reset_one():
    if cfg.always_show_one:
        if cfg.reset_show_one:
            cfg.show_one_on = False
        else:
            cfg.show_one_on = True    

def deal_e(pos_check = True):
    print('deal_e')    
    x, y = getp(None, False)
    sx, sy = cfg.fix_pos
    dx = x - sx
    dy = y - sy
    
    dx = round(dx*float(cfg.sum) + dx)
    dy = round(dy*float(cfg.sum) + dy)
    
    cfg.fix_pos =  (sx + dx, sy + dy)
    if pos_check:
        cfg.set_fix_time = time.time()
    if str(cfg.sum) != '0':
        cfg.isShow = False
    else:
        cfg.isShow = True
    clear(False)
    mouse.Controller().position = (sx + dx, sy + dy)
    deal_reset_one()     

def deal_add():    
    cfg.w2_last_ge = 0
    cfg.w2_last_to = 0
    cfg.w2_last_dis = 0
    cfg.last_ge = 0
    cfg.w2_min_ge = 0
    cfg.to = 0
    if cfg.sum == '0':
        if cfg.isShow:
            cfg.isShow = False
            cfg.show_one_on = True
        else:
            cfg.isShow = True        
        return
    deal_e()

def deal_lock(a):    
    print('lock', a)    
    if a == 10:
        lock_min()
    if a == 5:
        lock_add()
    if a == 0:
        lock_step_clear()
    if a in arrm:
        dx, dy = arrm[a]
        mouse.Controller().move(dx*lock_get(), dy*lock_get())
        cfg.lock_xing_last_move =  (dx*lock_get(), dy*lock_get())
        
def replay(re):
    lock_step_clear()
    last = ''
    for i in re:
        if last == '.' and i == '0':
            i = '.'
        if i == '.':
            a = 10
        else:
            a = int(i)
        deal_lock(a)
        last = i
    lock_step_clear()
    
def deal_pressed():    
    if not cfg.is_pressed:
        mouse.Controller().press(mouse.Button.left)  
        cfg.is_pressed = True
    else:
        mouse.Controller().release(mouse.Button.left)
        cfg.is_pressed = False

def move_p(a):    
    a = str(a)
    print('move', a, cfg.pos_m)
    if type(cfg.pos_m) ==type({}) and a in cfg.pos_m:
        clear(False, False)
        cfg.fix_pos =  cfg.pos_m[a]    
        mouse.Controller().position = cfg.pos_m[a]
        deal_reset_one()  

def load_pos():    
    try:
        f = open(pos_json_path)
        cfg.pos_m = json.load(f)
        f.close()        
    except:
        cfg.pos_m = {}

def add_p(a):    
    a = str(a)
    load_pos()
    cfg.pos_m[a] = mouse.Controller().position
    print('pos', cfg.pos_m)
    try:
        f = open(pos_json_path, 'w')
        json.dump(cfg.pos_m, f, indent=4)
        f.close()        
    except Exception as e:
        print(e)
        
    print('add', a)    

def deal_set(st, a):    
    if a < 0:
        return False
    
    if a >= 0 and a <= 10:
        add_p(a)
        return False
    
    return False    
 